// Infrastructure/Repositories/MenuRepository.cs
using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories;
using UniversalAdmin.Infrastructure.Data;

namespace UniversalAdmin.Infrastructure.Repositories;

public class MenuRepository : BaseRepository<Menu>, IMenuRepository
{
  public MenuRepository(UniversalAdminDbContext context) : base(context) { }

  public async Task<IEnumerable<Menu>> GetHierarchicalMenusAsync()
  {
    // 获取所有菜单并按Sort排序
    var allMenus = await _context.Menus
        .OrderBy(m => m.Sort)
        .AsNoTracking()
        .ToListAsync();

    // 使用内存中构建层级结构
    var menuLookup = allMenus.ToLookup(m => m.ParentId);

    // 构建层级关系
    foreach (var menu in allMenus)
    {
      // 通过ParentMenu导航属性建立关系
      if (menu.ParentId.HasValue)
      {
        var parent = allMenus.FirstOrDefault(m => m.Id == menu.ParentId.Value);
        if (parent != null)
        {
          menu.ParentMenu = parent;
        }
      }
    }

    // 返回顶级菜单（ParentId为null的菜单）
    return menuLookup[null].ToList();
  }

  public async Task<(IEnumerable<Menu> Items, int TotalCount)> GetPagedMenusAsync(
    string? keyword = null,
    bool? isActive = null,
    int pageIndex = 1,
    int pageSize = 10)
  {
    var query = _context.Menus.AsQueryable();

    if (!string.IsNullOrWhiteSpace(keyword))
      query = query.Where(m => m.Name.Contains(keyword));

    if (isActive.HasValue)
      query = query.Where(m => m.IsActive == isActive.Value);

    var total = await query.CountAsync();
    var items = await query
        .OrderBy(m => m.Sort)
        .Skip((pageIndex - 1) * pageSize)
        .Take(pageSize)
        .ToListAsync();

    return (items, total);
  }

  public async Task<IEnumerable<Menu>> GetMenusByParentIdAsync(int? parentId)
  {
    return await _context.Menus
        .Where(m => m.ParentId == parentId)
        .OrderBy(m => m.Sort)
        .ToListAsync();
  }

  public async Task<IEnumerable<Menu>> GetMenusByRoleIdAsync(int roleId)
  {
    return await _context.Menus
        .Where(m => m.RoleMenus.Any(rm => rm.RoleId == roleId))
        .OrderBy(m => m.Sort)
        .ToListAsync();
  }

  public async Task<IEnumerable<Menu>> GetAccessibleMenusAsync(IEnumerable<int> roleIds)
  {
    return await _context.Menus
        .Where(m => m.RoleMenus.Any(rm => roleIds.Contains(rm.RoleId)))
        .OrderBy(m => m.Sort)
        .ToListAsync();
  }

  public async Task ReorderMenusAsync(int parentId, IEnumerable<int> orderedMenuIds)
  {
    // 获取指定父级下的所有菜单
    var menus = await _context.Menus
        .Where(m => m.ParentId == parentId)
        .ToListAsync();

    // 创建排序字典
    var orderDict = orderedMenuIds
        .Select((id, index) => new { Id = id, Sort = index + 1 })
        .ToDictionary(x => x.Id, x => x.Sort);

    // 更新排序值
    foreach (var menu in menus)
    {
      if (orderDict.TryGetValue(menu.Id, out var newSort))
      {
        menu.Sort = newSort;
      }
    }

    await _context.SaveChangesAsync();
  }
  public async Task<IEnumerable<Menu>> GetMenusFlatAsync()
  {
    return await _context.Menus
        .AsNoTracking()
        .OrderBy(m => m.Sort)
        .ToListAsync();
  }

}